package com.smart.wap.service;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson2.JSONObject;
import com.smart.common.entities.ajax.AjaxResult;
import com.smart.common.entities.domain.LoginResult;
import com.smart.common.entities.enums.SmsScene;
import com.smart.common.exception.SmartException;
import com.smart.manager.pop.entities.models.PopDisInviter;
import com.smart.manager.pop.entities.models.query.QPopDisInviter;
import com.smart.manager.system.repository.ConfigRepository;
import com.smart.manager.weixin.mp.handler.WxmpHandler;
import com.smart.manager.weixin.mp.repository.WxmpAccountRepository;
import com.smart.service.sms.SmsService;
import com.smart.utils.WorkAcl;
import com.smart.wap.bodys.PopLoginBody;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Optional;

/**
 * 公众号接口
 *
 * @author leo
 * @date 2023/11/08
 */

@Service
@RequiredArgsConstructor
@Slf4j
public class WebsiteService {

    private final ConfigRepository configRepository;
    private final WxMpService wxMpService;
    private final SmsService smsService;

    private final WxmpAccountRepository wxmpAccountRepository;

    private final WxmpHandler wxmpHandler;

    /**
     * 微信授权跳转
     * @param agentId
     */
    public void wxLogin(HttpServletResponse response,String agentId) {
        JSONObject readCache = configRepository.readCache("H5URL");
        String url1 = readCache.getString("url");
        //获取appid
        WxMpService wxMpService1 = wxMpService.switchoverTo(wxmpAccountRepository.getDefaultAppId());
        WxOAuth2Service service = wxMpService1.getOAuth2Service();
        String url = service.buildAuthorizationUrl(url1, "snsapi_base", agentId);
        try {
            response.sendRedirect(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    /**
     * 获取验证码
     *
     * @param body 手机号
     */
    public void getAuthCode(PopLoginBody.authCodeBody body) {
        Optional<PopDisInviter> staff = new QPopDisInviter().phone.eq(body.getPhone()).setMaxRows(1).findOneOrEmpty();
        Assert.isFalse(staff.isEmpty(), "没有该账号请联系管理员开通!");
        smsService.sendCaptchaCode(SmsScene.WORKER_LOGIN, body.getPhone());
    }


    public AjaxResult<String> wxLogin2(String agentId) {
        JSONObject readCache = configRepository.readCache("H5URL");
        String url1 = readCache.getString("url");
        //获取appid
        WxMpService wxMpService1 = wxMpService.switchoverTo(wxmpAccountRepository.getDefaultAppId());
        WxOAuth2Service service = wxMpService1.getOAuth2Service();
        String snsapiBase = service.buildAuthorizationUrl(url1, "snsapi_base", agentId);
        return AjaxResult.data(snsapiBase);
    }

    /**
     * @return {@link LoginResult}
     */
    public LoginResult getAccessToken(PopLoginBody.LoginBody body) {

        try {
            log.warn("wxmpAccountRepository.getDefaultAppId() ={}",wxmpAccountRepository.getDefaultAppId());
            WxMpService wxMpService1 = wxMpService.switchoverTo(wxmpAccountRepository.getDefaultAppId());
            WxOAuth2AccessToken accessToken = wxMpService1.getOAuth2Service().getAccessToken(body.getCode());
            String openId = accessToken.getOpenId();
            log.warn("openId = {}",openId);
            WxOAuth2UserInfo userInfo = wxMpService1.getOAuth2Service().getUserInfo(accessToken, "zh_CN");
            log.warn("Access token {}", openId);
            Optional<PopDisInviter> oneOrEmpty = new QPopDisInviter().openid.eq(openId).setMaxRows(1).findOneOrEmpty();
            PopDisInviter agent = null;
            //注册
            agent = oneOrEmpty.orElseGet(() -> enroll(userInfo, body.getActing()));

            if (ObjUtil.isNotNull(agent)) {
                return loginSuccessHandler(agent, true);
            }
            return new LoginResult().setSuccess(false).setTips("登录失败,请继续使用手机短信验证码登录").setOpenId(openId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new SmartException(e.getMessage());
        }


    }

    private LoginResult loginSuccessHandler(PopDisInviter agent, boolean isUpdate) {
        String accessToken = WorkAcl.login(agent.getId());
        String refreshToken = DigestUtil.md5Hex(accessToken).toUpperCase();
        //记录会员登录时间 并设置会员刷新令牌有效期和值 刷新令牌有效期为6个月
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime refreshExpiredTime = now.plusMonths(6L);
        LoginResult loginResult = new LoginResult().setSuccess(true).setTips("登录成功！").setAccessToken(accessToken).setRefreshToken(refreshToken).setOpenId(agent.getOpenid());
        agent.setRefreshToken(refreshToken).setRefreshExpiredTime(refreshExpiredTime);
        //修改描述下 刷新数据
        if (isUpdate) {
            agent.update();
            return loginResult;
        }
        return loginResult;
    }

    /**
     * 注册
     */
    private PopDisInviter enroll(WxOAuth2UserInfo info, Long acting) {
        PopDisInviter PopDisInviter = new PopDisInviter()
                .setAmount(BigDecimal.ZERO)   //设置金额
                .setAmountCont(BigDecimal.ZERO) //设置总金额
                .setDepositFee(BigDecimal.ZERO) //设置总金额
                .setStatus(true)  //设置状态
                .setAvatar(info.getHeadImgUrl()) //设置默认头像
                .setOpenid(info.getOpenid())  //设置openid
                .setLevel(null)  //设置为普通用户
                .setRts1(0).setRts2(0)
                .setName(info.getNickname());
        if (ObjUtil.isNotNull(acting)) {
            new QPopDisInviter().id.eq(acting).setMaxRows(1).findOneOrEmpty().ifPresent(agent -> {
                //设置上级代理
                    PopDisInviter.setParentId(acting);
                agent.setRts1(agent.getRts1() + 1).update();
            });
        }
        PopDisInviter.insert();
        return PopDisInviter;
    }


    public void LogInForTheFirstTime(WxOAuth2UserInfo info, PopDisInviter popDisInviter) {
        popDisInviter
                .setAvatar(info.getHeadImgUrl()) //设置默认头像
                .setOpenid(info.getOpenid())  //设置openid
                .setName(info.getNickname());
    }


    /**
     * 获取自己账户简单信息
     *
     * @return {@code SystemAccount}
     */
//    public AgentUser getSimpleAccount() {
//        Long loginId = WorkAcl.getLoginId();
//        if (ObjectUtil.isEmpty(loginId)) {
//            throw new AccountException("账号查询失败");
//        }
//        AgentUser agentUser = cacheService.getAgentUserCache().get(loginId);
//        log.warn("agentUser = {}", agentUser);
//        if (ObjectUtil.isNull(agentUser)) {
//            log.warn("通过数据库查找");
//            Optional<PopDisInviter> agent = new QDistributorAgent().id.eq(loginId).setMaxRows(1).findOneOrEmpty();
//            if (agent.isPresent()) {
//                AgentUser agentUser1 = BeanUtil.copyProperties(agent.get(), AgentUser.class);
//                Opt.ofBlankAble(agent.get().getManagerId()).ifPresent(x -> {
//                    agentUser1.setManagerId(BeanUtil.copyProperties(x, Manager.class));
//                });
//                Opt.ofBlankAble(agent.get().getSuperiorCode()).ifPresent(x -> {
//                    agentUser1.setSuperiorCode(BeanUtil.copyProperties(x, Agent.class));
//                });
//                //查询今日收益
//                BigDecimal sum = new QDistributorTransaction().agentId.id.eq(agentUser1.getId()).arithmetic.eq(TransactionState.REVENUE)
//                        .createTime.between(LocalDateTimeUtil.of(DateUtil.date(CalendarUtils.getTodayStart())), LocalDateTimeUtil.now())
//                        .findList().stream().map(DistributorTransaction::getAmount).collect(Collectors.toList()).stream()
//                        .reduce(BigDecimal.ZERO, BigDecimal::add);
//                agentUser1.setToday(sum);
//                cacheService.getAgentUserCache().put(loginId, agentUser1);
//                return agentUser1;
//            }
//        }
//        log.warn("通过缓存查找");
//        return agentUser;
//    }
    public PopDisInviter getAccount() {
        Optional<PopDisInviter> oneOrEmpty = new QPopDisInviter().id.eq(WorkAcl.getLoginId()).setMaxRows(1).findOneOrEmpty();
        Assert.isFalse(oneOrEmpty.isEmpty(), "未查到账号!");
        return oneOrEmpty.get();
    }


    /**
     * 验证码登录
     *
     * @param body 手机号 ,验证码
     * @return {@link LoginResult}
     */
    public LoginResult authCodeLogin(PopLoginBody.authCodeLoginBody body) {
        Optional<PopDisInviter> staff = new QPopDisInviter().phone.eq(body.getPhone()).setMaxRows(1).findOneOrEmpty();
        Assert.isFalse(staff.isEmpty(), "没有该账号请联系管理员开通!");
        smsService.checkCaptchaCode(SmsScene.POP_REVISE, body.getPhone(), body.getAuthCode());
        PopDisInviter inviter = staff.get();
        if (inviter.getOpenid() == null) {
            //首次绑定
            try {
                WxMpService wxMpService1 = wxMpService.switchoverTo(wxmpAccountRepository.getDefaultAppId());
                WxOAuth2AccessToken accessToken = wxMpService1.getOAuth2Service().getAccessToken(body.getWxCode());
                String openId = accessToken.getOpenId();
                WxOAuth2UserInfo userInfo = wxMpService1.getOAuth2Service().getUserInfo(accessToken, "zh_CN");
                LogInForTheFirstTime(userInfo,inviter);
                inviter.setOpenid(openId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return loginSuccessHandler(inviter, true);
    }

}
